
enum AddType {
  day,
  month,
  year,
}
class DateTools {
  static String formatTime(timeStamp, {format = "{y}-{m}-{d} {h}:{i}:{s}"}) {
    if(timeStamp == null) return "";
    if ("$timeStamp".length == 10) {
      timeStamp *= 1000;
    }
    DateTime date = DateTime.fromMillisecondsSinceEpoch(timeStamp);
    var formatObj = {
      "y": date.year,
      "m": date.month,
      "d": date.day,
      "h": date.hour,
      "i": date.minute,
      "s": date.second,
      "a": date.weekday,
    };
    RegExp exp = RegExp("{(y|m|d|h|i|s|a)+}");
    String timeStr = format.replaceAllMapped(exp, (Match match) {
      var result = match.group(0); // {m}
      var key = match.group(1); // m
      var value = formatObj[key];
      if (key == "a") return ["一", "二", "三", "四", "五", "六", "日"][value! - 1];
      var s = "$value";
      if (result!.isNotEmpty && value! < 10) {
        s = "0$value";
      }
      return s;
    });
    return timeStr;
  }

  static String formatYMD(dynamic date, { String? format }) {
    dynamic timeStamp;
    if (date is String && date.isNotEmpty) {
      timeStamp = DateTime.parse(date).millisecondsSinceEpoch;
    } else if (date is int && date.toString().length >= 10) {
      timeStamp = date;
      if (date.toString().length == 10) {
        timeStamp = date * 1000;
      }
    } else if (date is DateTime) {
      timeStamp = date.millisecondsSinceEpoch;
    } else {
      return "";
    }
    return formatTime(timeStamp, format: format ?? "{y}-{m}-{d}");
  }

  static getWeek(timeStamp) {
    if(timeStamp == null) return null;
    String week = "";
    if ("$timeStamp".length == 10) {
      timeStamp *= 1000;
    }
    DateTime date = DateTime.fromMillisecondsSinceEpoch(timeStamp);
    if (date.weekday == 0) week = "星期日";
    if (date.weekday == 1) week = "星期一";
    if (date.weekday == 2) week = "星期二";
    if (date.weekday == 3) week = "星期三";
    if (date.weekday == 4) week = "星期四";
    if (date.weekday == 5) week = "星期五";
    if (date.weekday == 6) week = "星期六";
    return week;
  }

  static bool isLeapYear(int year) {
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
  }

  /// 日期操作 增加或者减

  static DateTime add(dynamic date, { required AddType type, int? num, }) {
    dynamic timeStamp;
    if (date is String && date.isNotEmpty) {
      timeStamp = DateTime.parse(date).millisecondsSinceEpoch;
    } else if (date is int && date.toString().length >= 10) {
      timeStamp = date;
      if (date.toString().length == 10) {
        timeStamp = date * 1000;
      }
    } else if (date is DateTime) {
      timeStamp = date.millisecondsSinceEpoch;
    } else {
      timeStamp = DateTime.now();
    }

    DateTime originDate = DateTime.fromMillisecondsSinceEpoch(timeStamp);
    int originDay = originDate.day;
    int originMonth = originDate.month;
    int originYear = originDate.year;
    int originHour = originDate.hour;
    int originMinute = originDate.minute;
    int originSecond = originDate.second;

    DateTime createDate;
    List<int> smallMonth = [4, 6, 9, 11];

    switch(type) {
      case AddType.day:
        originDate.add(Duration(days: num ?? 1));
        createDate = originDate;
        break;
      case AddType.month:
        int newMonth = (originMonth + (num ?? 1)) % 12 == 0 ? 12 : (originMonth + (num ?? 1)) % 12;
        int year = originYear + ((originMonth + (num ?? 1) - 1) ~/ 12);
        print("originYear: $originYear, newMonth: $newMonth, newMonth % 12: ${newMonth ~/ 12}");
        int day = 0;
        if (newMonth == 2) {
          if (isLeapYear(year)) {
            originDay > 29 ? day = 29 : day = originDay - 1;
          } else {
            originDay > 28 ? day = 28 : day = originDay - 1;
          }
        } else {
          if (smallMonth.contains(newMonth)) {
            originDay > 30 ? day = 30 : day = originDay - 1;
          } else {
            day = originDay - 1;
          }
        }
        createDate = DateTime(year, newMonth, day, originHour, originMinute, originSecond);
        break;
      case AddType.year:
        int year = originYear + (num ?? 1);
        int day = 0;
        if (originMonth == 2) {
          if (isLeapYear(year)) {
            originDay > 29 ? day = 29 : day = originDay - 1;
          } else {
            originDay > 28 ? day = 28 : day = originDay - 1;
          }
        } else {
          if (smallMonth.contains(originMonth)) {
            originDay > 30 ? day = 30 : day = originDay - 1;
          } else {
            day = originDay - 1;
          }
        }
        createDate = DateTime(year, originMonth, day, originHour, originMinute, originSecond);
        break;
    }

    return createDate;

  }
}